package com.demo2.todo.controller;

import com.demo2.todo.exception.BadRequestException;
import com.demo2.todo.exception.UnauthorizedException;
import com.demo2.todo.model.dto.AuthRequest;
import com.demo2.todo.model.dto.AuthResponse;
import com.demo2.todo.model.entity.User;
import com.demo2.todo.security.JwtTokenProvider;
import com.demo2.todo.service.UserService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author evi
 */
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
    private final UserService userService;
    private final JwtTokenProvider jwtTokenProvider;
    private final UserDetailsService userDetailsService;

    @PostMapping("/register")
    public ResponseEntity<AuthResponse> register(@Valid @RequestBody AuthRequest request) {
        return ResponseEntity.ok(userService.register(request));
    }

    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@Valid @RequestBody AuthRequest request) {
        return ResponseEntity.ok(userService.login(request));
    }

    @PostMapping("/refresh")
    public ResponseEntity<AuthResponse> refreshToken(@RequestBody Map<String, String> tokenRequest) {
        String refreshToken = tokenRequest.get("refreshToken");

        if (refreshToken == null || refreshToken.isEmpty()) {
            throw new BadRequestException("刷新令牌不能为空");
        }

        try {
            // 从刷新令牌中提取用户名
            String username = jwtTokenProvider.extractUsername(refreshToken);
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            // 验证刷新令牌
            if (jwtTokenProvider.isTokenValid(refreshToken, userDetails)) {
                // 生成新的访问令牌
                String newAccessToken = jwtTokenProvider.generateAccessToken(userDetails);
                User user = (User) userDetails;

                return ResponseEntity.ok(AuthResponse.builder()
                        .id(user.getId())
                        .username(user.getUsername())
                        .accessToken(newAccessToken)
                        .refreshToken(refreshToken) // 可以选择是否也刷新刷新令牌
                        .isAdmin("ADMIN".equals(user.getRole()))
                        .build());
            } else {
                throw new UnauthorizedException("刷新令牌无效");
            }
        } catch (ExpiredJwtException e) {
            throw new UnauthorizedException("刷新令牌已过期，请重新登录");
        } catch (JwtException e) {
            throw new UnauthorizedException("刷新令牌无效");
        }
    }
}

